/*
 * Copyright 2019 Web3 Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.web3j.web3jevmexample;

import org.web3j.crypto.Credentials;
import org.web3j.crypto.Hash;
import org.web3j.java.LinkToken;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetCode;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.tx.gas.DefaultGasProvider;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;


import java.math.BigDecimal;
import java.math.BigInteger;

public class Demo {

    public static void main(String... args) throws Exception {
        // 账户地址和私钥
        String fromAddress = "0x627306090abaB3A6e1400e9345bC60c78a8BEf57"; // 内置账户地址
        String privateKey = "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3";// 内置账户私钥
        Credentials originalCredentials = Credentials.create(privateKey);
        System.out.println("Original Credentials Address : " + originalCredentials.getAddress());

        //String linkTokenAddress = "0x8cdaf0cd259887258bc13a92c0a6da92698644c0";     // LINK 合约地址
        //String linkTokenEIP55 = "0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0";     // LINK 合约 EIP55 格式地址
        String linkTokenAddress = "0xf204a4ef082f5c04bb89f7d5e6568b796096735a";     // LINK 合约地址
        String linkTokenEIP55 = "0xf204a4Ef082f5c04bB89F7D5E6568B796096735a";     // LINK 合约 EIP55 格式地址

        String operatorAddress = "0xf12b5dd4ead5f743c6baa640b0216200e89b60da";      // Operator 合约地址
        String operatorEIP55 = "0xF12b5dd4EAD5F743C6BaA640B0216200e89B60Da";      // Operator 合约 EIP55 格式地址


        //String apiConsumerAddress = "0x9fbda871d559710256a2502a2517b794b482db40";   // APIConsumer合约地址( 0 fee )
        //String apiConsumerAddress = "0xde5491f774f0cb009abcea7326342e105dbb1b2e";   // APIConsumer合约地址 ( 100 fee )
        //String apiConsumerEIP55 = "0xdE5491f774F0Cb009ABcEA7326342E105dbb1B2E";   // APIConsumer合约地址 EIP55 格式地址
        String apiConsumerAddress = "0x8cdaf0cd259887258bc13a92c0a6da92698644c0";

        String atestnetConsumer = "0x8273e4b8ed6c78e252a9fca5563adfcc75c91b2a";     // ATestnetConsumer合约地址
        String evmChainAddress = "0x71965FB3ceAc089Fab7CC69a99C85E2397929523";      // EVM Chain Accounts (chainlink在私有链上的账户地址)
        String jobid = "8d8c66be716c4bcf9a59c5d8e70123db";

        //Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
        Web3j web3j = Web3j.build(new HttpService("http://192.168.1.162:8545"));

        // 生成一个钱包文件 (初始测试钱包)
        //String fileName = WalletUtils.generateNewWalletFile("abc123456",new File("resources/"));
        //System.out.println("Wallet file created: " + fileName);
        //
        //Credentials credentials0 = WalletUtils.loadCredentials("abc123456", "resources/"+fileName);
        //Configuration configuration0 = new Configuration(new Address(credentials0.getAddress()), 10000000000000L);
        //
        //// 加载钱包文件中的凭证 (测试钱包01)
        //Credentials credentials01 =
        //        WalletUtils.loadCredentials("Password123", "resources/demo-wallet.json");

        // 定义我们自己的地址以及预资助该地址的以太坊数量
        //Configuration configuration = new Configuration(new Address(credentials0.getAddress()), 90000L);
        //Configuration configuration = new Configuration(Address.DEFAULT, 90000L);

        // 使用控制台调试 tracer，可以查看每个操作的详细信息
        // 如果不需要控制台调试，可以使用 PassthroughTracer
        //OperationTracer operationTracer = new ConsoleDebugTracer();
        //OperationTracer operationTracer = new PassthroughTracer();

        // 使用 EmbeddedWeb3jService 实现，它允许我们在运行的 JVM 中运行 EVM 和账本
        //Web3j web3j = Web3j.build(new EmbeddedWeb3jService(configuration, OperationTracer.NO_TRACING));
        ////Web3j web3j = Web3j.build(new EmbeddedWeb3jService(configuration0, operationTracer));

        //
        //Storage.deploy(web3j, originalCredentials, new DefaultGasProvider()).send();
        //Storage storage = Storage.load(linkTokenAddress, web3j, originalCredentials, new DefaultGasProvider())


        //EthAccounts ethAccounts = web3j.ethAccounts().send();
        //for (String address : ethAccounts.getAccounts()) {
        //    System.out.println("Address : " + address.toString());
        //}
        //
        // 查询某个地址的余额
        BigInteger balance = web3j.ethGetBalance(fromAddress, DefaultBlockParameterName.LATEST).send().getBalance();
        System.out.println("fromAddress Balance: " + balance);

        //NetVersion nv = web3j.netVersion().send();
        //System.out.println("NetVersion : " + nv.getNetVersion());
        //Web3ClientVersion web3ClientVersion = web3j.web3ClientVersion().send();
        //String clientVersion = web3ClientVersion.getWeb3ClientVersion();
        //System.out.println("ClientVersion : " + clientVersion);

        // 基础费,它用不是支付给矿工的，而是被销毁掉，以减少以太坊的总供应量
        //EthBaseFee ethBaseFee =   web3j.ethBaseFee().send();
        //System.out.println("BaseFee : " + ethBaseFee.getBaseFee());

        //EthGetBalance fromAddrBalance = web3j.ethGetBalance(fromAddress, DefaultBlockParameterName.LATEST).send();
        //System.out.println("firstSearch fromAddrBalance : " + fromAddrBalance.getBalance());


/**
        LinkToken linkToken = LinkToken.load(linkTokenAddress,web3j,originalCredentials,new DefaultGasProvider());

        //查询link余额
        BigInteger fromAddressBalance = linkToken.balanceOf(fromAddress).send();
        System.out.println("fromAddressBalance LinkToken Balance: " +fromAddressBalance );
        //BigInteger linkAddressBalance = linkToken.balanceOf("0x8f0483125fcb9aaaefa9209d8e9d7b9c8b9fb90f").send();
        //System.out.println("linkAddress LinkToken Balance: " + linkAddressBalance );


        // 给 atestnetConsumer 地址转账 一定数额的 LINK币
        linkToken.transfer(apiConsumerAddress, BigInteger.valueOf(999999999L)).send();
        BigInteger apiConsumerBalance = linkToken.balanceOf(apiConsumerAddress).send();
        System.out.println("apiConsumerAddress LinkToken Balance: " +apiConsumerBalance );
*/


/**
        LinkToken linkToken = LinkToken.load(linkTokenAddress,web3j,originalCredentials,new DefaultGasProvider());
        BigInteger amount2 = BigInteger.valueOf(100000).multiply(BigInteger.TEN.pow(18)); // 铸造 10000000 LINK（假设 1 LINK = 10^18 Wei）

        //查询operator地址的link余额
        BigInteger operatorAddressBalance = linkToken.balanceOf(operatorAddress).send();
        System.out.println("operatorAddress LinkToken Balance: " +operatorAddressBalance );
        BigInteger evmChainAddressBalance = linkToken.balanceOf(evmChainAddress).send();
        System.out.println("evmChainAddress LinkToken Balance: " + evmChainAddressBalance );

        // 给 atestnetConsumer 地址转账 一定数额的 LINK币
        linkToken.transfer(operatorAddress, amount2).send();
        linkToken.transfer(evmChainAddress, amount2).send();
        //查询operator地址的link余额
        BigInteger operatorAddressBalance2 = linkToken.balanceOf(operatorAddress).send();
        System.out.println("operatorAddress2 LinkToken Balance: " +operatorAddressBalance2 );
        BigInteger evmChainAddressBalance2 = linkToken.balanceOf(evmChainAddress).send();
        System.out.println("evmChainAddress2 LinkToken Balance: " + evmChainAddressBalance2 );
*/


/**
        LinkToken linkToken = LinkToken.load(linkTokenAddress,web3j,originalCredentials,new DefaultGasProvider());
        BigInteger amount = BigInteger.valueOf(100000).multiply(BigInteger.TEN.pow(18)); // 铸造 10000000 LINK（假设 1 LINK = 10^18 Wei）
        BigInteger amount2 = BigInteger.valueOf(11111).multiply(BigInteger.TEN.pow(18));

        TransactionReceipt receipt = linkToken.grantMintRole(fromAddress).send();
        System.out.println("授权成功，已给予 " + fromAddress + " 铸币权限 ");

        // 调用 approve 方法
        linkToken.approve(fromAddress, amount).send();
        System.out.println("授权成功，已给予 " + fromAddress + " 铸币额度 : " + amount);
        // 调用 approve 方法
        //linkToken.approve(linkTokenAddress, amount).send();
        //System.out.println("授权成功，已给予 " + linkTokenAddress + " 铸币权限 " + amount);

        // 查询合约所有者  合约所有者地址: 0x627306090abab3a6e1400e9345bc60c78a8bef57
        //String owner = linkToken.owner().send();
        //System.out.println("合约所有者地址: " + owner);

        TransactionReceipt mintReceipt = linkToken.mint(fromAddress, amount).send();
        // 检查 mint 的交易收据
        if (mintReceipt.getStatus().equals("0x0")) {
            System.out.println("mint 交易失败，原因: " + mintReceipt.getRevertReason());
        }else {
            System.out.println("铸币成功");
        }
        BigInteger fromAddressBalance = linkToken.balanceOf(fromAddress).send();
        System.out.println("fromAddress LINK Balance: " + fromAddressBalance);

        //BigInteger evmChainAddressBalance = linkToken.balanceOf(evmChainAddress).send();
        //System.out.println("evmChainAddress LINK Balance: " + evmChainAddressBalance);

        //approveTokens(linkToken,fromAddress,amount2); // 授权给 内置账户地址 10000000 LINK
        approveTokens(linkToken,apiConsumerAddress,amount2); // 授权给 apiConsumer 合约地址 10000000 LINK
        //approveTokens(linkToken,operatorAddress,amount2); // 授权给 operator 合约地址 10000000 LINK
        //approveTokens(linkToken,evmChainAddress,amount2); // 授权给 链下预言机地址 10000000 LINK

        BigInteger apiConsumerAddressBalance1 = linkToken.balanceOf(apiConsumerAddress).send();
        System.out.println("转账前,apiConsumerAddress LinkToken Balance: " + apiConsumerAddressBalance1);
        TransactionReceipt transferReceipt = linkToken.transfer(apiConsumerAddress, amount2).send();
        // 查询apiConsumer地址的link余额
        BigInteger apiConsumerAddressBalance2 = linkToken.balanceOf(apiConsumerAddress).send();
        System.out.println("转账后,apiConsumerAddress LinkToken Balance: " + apiConsumerAddressBalance2);
*/


/**
        LinkToken linkToken = LinkToken.load(linkTokenAddress,web3j,originalCredentials,new DefaultGasProvider());
        BigInteger amount2 = BigInteger.valueOf(100000).multiply(BigInteger.TEN.pow(18)); // 铸造 10000000 LINK（假设 1 LINK = 10^18 Wei）
        // 调用 mint 方法
        TransactionReceipt mintReceipt = linkToken.mint(operatorAddress, amount2).send();
        System.out.println("铸币成功");

        // 检查 mint 的交易收据
        if (mintReceipt.getStatus().equals("0x0")) {
            System.out.println("mint 交易失败，原因: " + mintReceipt.getRevertReason());
        }
*/



 /**
        //查询交易记录
        EthGetTransactionReceipt receipt = web3j.ethGetTransactionReceipt(transactionHash).send();
        Optional<TransactionReceipt> transactionReceipt = receipt.getTransactionReceipt();

        if (transactionReceipt.isPresent()) {
            List<Log> logs = transactionReceipt.get().getLogs();
            for (Log log : logs) {
                System.out.println("Log: " + log.getData());
            }
        }
*/

        //linkToken.mint(fromAddress, BigInteger.valueOf(1000000000000000000L)).send();
/**
        // 查询某个地址的余额
        BigInteger balance = linkToken.balanceOf(evmChainAddress).send();
        System.out.println("LINK Token Balance: " + balance);
*/


        //Request<?, EthGetBalance> request = web3j.ethGetBalance(credentials0.getAddress(), DefaultBlockParameterName.LATEST);
        ////获取request里的EthGetBalance
        //EthGetBalance ethGetBalance0 = request.send();
        //System.out.println("First search Current balance(0) : " + ethGetBalance0.getBalance());
        //EthGetBalance ethGetBalance01 = web3j.ethGetBalance(credentials01.getAddress(), DefaultBlockParameterName.LATEST).send();
        //System.out.println("First search Current balance(01) : " + ethGetBalance01.getBalance());


/**
        EthGetBalance ethGetBalance =web3j.ethGetBalance(originalCredentials.getAddress(), DefaultBlockParameterName.LATEST).send();
        System.out.println(" *** First search Current balance(wei)-1Ether(ETH)等于10的18次方Wei: " + ethGetBalance.getBalance());
        BigDecimal balanceInEther = Convert.fromWei(ethGetBalance.getBalance().toString(), Convert.Unit.ETHER);
        System.out.println("当前余额 (ETH): " + balanceInEther);

        // 执行一个简单的 ETH 转账交易
        System.out.println("Starting simple ETH transfer transaction");

        // 使用 Web3j 进行转账
        //sendEther2(web3j, fromAddress, privateKey, credentials0.getAddress(), new BigInteger("22222"));
         //* 发送资金到指定地址
        TransactionReceipt transactionReceipt =
                Transfer.sendFunds(
                        web3j,    //Web3j实例，用于连接以太坊节点
                        originalCredentials,    //发送资金的账户凭证，包含私钥
                        evmChainAddress,        //接收资金的以太坊地址
                        new BigDecimal("100000"),    //转账金额，以指定单位表示
                        Convert.Unit.ETHER)    //转账金额的单位，如WEI、ETHER等
                        .send();

        System.out.println(
                "合约地址 : " + transactionReceipt.getContractAddress());
        // 打印交易收据的哈希值
        System.out.println(
                "Transfer transaction receipt: " + transactionReceipt.getTransactionHash());
        // 如果交易失败，抛出异常
        if (!transactionReceipt.isStatusOK()) throw new RuntimeException("Failed transaction");

        EthGetBalance ethGetBalanceSecont0 =web3j.ethGetBalance(evmChainAddress, DefaultBlockParameterName.LATEST).send();
        System.out.println(" *** Second search Current balance(02): " + ethGetBalanceSecont0.getBalance());
*/

        //BigInteger blockGasLimit = web3j.ethGetBlockByNumber(DefaultBlockParameterName.LATEST, false)
        //        .send().getBlock().getGasLimit();
        //System.out.println("Current block gas limit: " + blockGasLimit);

        String targetAddress = "0x7877519648D20C81B8C33F48C2cf82f25Bd9e533";

        EthGetBalance ethGetBalance =web3j.ethGetBalance(targetAddress, DefaultBlockParameterName.LATEST).send();
        System.out.println(" *** First search Current balance(wei)-1Ether(ETH)等于10的18次方Wei: " + ethGetBalance.getBalance());
        BigDecimal balanceInEther = Convert.fromWei(ethGetBalance.getBalance().toString(), Convert.Unit.ETHER);
        System.out.println("当前余额 (ETH): " + balanceInEther);

        // 执行一个简单的 ETH 转账交易
        System.out.println("Starting simple ETH transfer transaction");

        //BigInteger gasLimit = BigInteger.valueOf(21000); // 根据需要调整
        //BigInteger gasPrice = BigInteger.valueOf(20000000000L); // 20 Gwei

        // 使用 Web3j 进行转账
        //sendEther2(web3j, fromAddress, privateKey, credentials0.getAddress(), new BigInteger("22222"));
        //* 发送资金到指定地址
        TransactionReceipt transactionReceipt =
                Transfer.sendFunds(
                                web3j,    //Web3j实例，用于连接以太坊节点
                                originalCredentials,    //发送资金的账户凭证，包含私钥
                                targetAddress,        //接收资金的以太坊地址
                                BigDecimal.valueOf(100),    //转账金额，以指定单位表示
                                Convert.Unit.ETHER
                        )    //转账金额的单位，如WEI、ETHER等

                        .send();

        // 打印交易收据的哈希值
        System.out.println(
                "Transfer transaction receipt: " + transactionReceipt.getTransactionHash());
        // 如果交易失败，抛出异常
        if (!transactionReceipt.isStatusOK()) throw new RuntimeException("Failed transaction");

        EthGetBalance ethGetBalanceSecont0 =web3j.ethGetBalance(targetAddress, DefaultBlockParameterName.LATEST).send();
        System.out.println(" *** Second search Current balance(02): " + ethGetBalanceSecont0.getBalance());

/**
        // 要检查的地址,判断是合约地址还是外部钱包地址
        String targetAddress = "0x7877519648D20C81B8C33F48C2cf82f25Bd9e533";

        // 获取地址的代码
        EthGetCode ethGetCode = web3j.ethGetCode(apiConsumerAddress, DefaultBlockParameterName.LATEST).send();
        String code = ethGetCode.getCode();

        // 检查地址是否为合约
        if (code.equals("0x")) {
            System.out.println("目标地址是一个外部账户，能够接收 ETH。");
        } else {
            System.out.println("目标地址是一个合约地址。");
            // 进一步检查合约是否有 payable 函数的逻辑
            // 这里可能需要其他的合约 ABI 信息来确认
        }
*/

/**
        // 预估gas用量
        EthEstimateGas ethEstimateGas =web3j.ethEstimateGas(
                        Transaction.createContractTransaction(
                                fromAddress, // 发起交易的地址
                                BigInteger.ZERO, // 交易的nonce值，用于防止重放攻击和确保交易顺序
                                BigInteger.TEN, // 交易的gas价格，单位为wei
                                TestStorage.BINARY))    // init 合约初始化字节码
                        .send();
        BigInteger gasEstimate = ethEstimateGas.getAmountUsed();
        int sign = gasEstimate.signum();
        switch (sign) {
            case -1:
                // 处理错误
                System.err.println("估计Gas用量为负数，出现错误");
                // 记录错误日志，采取相应措施
                break;
            case 0:
                // 进一步检查
                System.out.println("估计Gas用量为零，需要进一步检查");
                // 进行进一步检查
                break;
            case 1:
                // 继续交易处理
                System.out.println("估计Gas用量为正数，gasEstimate: " + gasEstimate+", 继续交易处理");
                // 签名并发送交易
                break;
            default:
                // 不应该到达这里
                System.err.println("未知的符号值");
                break;
        }



        // 设置较低的Gas价格和Gas限制
        BigInteger gasLimit = BigInteger.valueOf(100_000); // 4 million Ga s
        BigInteger gasPrice = BigInteger.valueOf(10); // 10 Gwei
        StaticGasProvider gasProvider = new StaticGasProvider(gasPrice, gasEstimate.add(gasLimit));
 */

/**
        System.out.println("Starting Greeter TestStorage..");
        TestStorage ts = TestStorage.deploy(web3j, originalCredentials, new DefaultGasProvider(),"hello world111").send();
        //TestStorage.deploy(web3j, originalCredentials, gasProvider);
        //TestStorage ts = TestStorage.deploy(web3j, credentials, gasProvider).send();
        System.out.println("TestStorage , success !!! ");
        System.out.println("TestStorage address: " + ts.getContractAddress());
        String str01 =ts.get().send();
        System.out.println("TestStorage  get() str01: " + str01);
 */



        //HelloWorld helloWorld = HelloWorld.deploy(web3j, originalCredentials, new DefaultGasProvider(), "Hello World!").send();
        //System.out.println("HelloWorld address: " + helloWorld.getContractAddress());
        //String str01 =helloWorld.print().send();
        //System.out.println("helloWorld str01: " + str01);

        //HelloWorld loadHelloWorld  = HelloWorld.load("0x8cdaf0cd259887258bc13a92c0a6da92698644c0",web3j,originalCredentials,new DefaultGasProvider());





        //APIConsumer apiConsumer =APIConsumer.load(toChecksumAddress("0x8273e4b8ed6c78e252a9fca5563adfcc75c91b2a"),web3j,originalCredentials,new DefaultGasProvider());
        //TransactionReceipt apiConsumerReceipt = apiConsumer.requestVolumeData().send();
        //System.out.println("调用APIConsumer requestVolumeData 交易成功");
        //BigInteger apiConsumerVolume = apiConsumer.volume().send();
        //System.out.println("APIConsumer volume: " + apiConsumerVolume);




        web3j.shutdown();
    }

    private static void sendEther1(Web3j web3j, String fromAddress, String privateKey, String toAddress, BigInteger amount) {
        try {
            // 创建凭证对象
            Credentials credentials = Credentials.create(privateKey);

            // 创建转账交易
            Transaction transaction = Transaction.createEtherTransaction( fromAddress, new BigInteger("1"), DefaultGasProvider.GAS_PRICE,  DefaultGasProvider.GAS_LIMIT, toAddress, amount);

            // 发送交易
            EthSendTransaction response = web3j.ethSendTransaction(transaction).send();



            // 获取交易哈希
            String transactionHash = response.getTransactionHash();
            System.out.println("Transaction hash: " + transactionHash);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void sendEther2(Web3j web3j, String fromAddress, String privateKey, String toAddress, BigInteger amount) {
        try {
            // 创建凭证对象
            Credentials credentials = Credentials.create(privateKey);

            // 获取当前 nonce
            BigInteger nonce = web3j.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.LATEST)
                    .send().getTransactionCount();


            //// 创建交易
            //BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();
            //Transaction transaction = Transaction.createEtherTransaction(
            //        fromAddress,
            //        nonce,
            //        value,
            //        DefaultGasProvider.GAS_LIMIT,
            //        toAddress
            //);
            //
            //// 签名交易
            //String signedTransaction = credentials.signTransaction(transaction).getTransaction();
            //
            //credentials.
            //
            //// 发送已签名的交易
            //EthSendTransaction response = web3j.ethSendRawTransaction(signedTransaction).send();
            //
            //// 获取交易哈希
            //String transactionHash = response.getTransactionHash();
            //System.out.println("Transaction hash: " + transactionHash);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static String toChecksumAddress(String address) {
        if ((address != null && !address.trim().isEmpty()) && address.startsWith("0x")) {
            String addressWithoutPrefix = address.substring(2);
            String hashedAddress = Numeric.toHexStringNoPrefix(Hash.sha3(addressWithoutPrefix.toLowerCase().getBytes()));

            StringBuilder checksumAddress = new StringBuilder("0x");
            for (int i = 0; i < addressWithoutPrefix.length(); i++) {
                // 根据哈希值的每个字符决定当前字符是大写还是小写
                if (Integer.parseInt(String.valueOf(hashedAddress.charAt(i)), 16) > 7) {
                    checksumAddress.append(Character.toUpperCase(addressWithoutPrefix.charAt(i)));
                } else {
                    checksumAddress.append(addressWithoutPrefix.charAt(i));
                }
            }
            return checksumAddress.toString();
        }
        throw new IllegalArgumentException("Invalid address format");
    }


    // 增加授权，允许指定的合约地址花费一定数量的 LINK 代币
    public static void approveTokens(LinkToken linkToken, String spenderAddress, BigInteger amount) throws Exception {
        // 增加授权，允许指定的合约地址花费一定数量的 LINK 代币
        TransactionReceipt approvalReceipt = linkToken.approve(spenderAddress, amount).send();
        System.out.println("Approved " + amount + " LINK for spender: " + spenderAddress);
    }


}

